﻿@using System.Diagnostics.CodeAnalysis
@using System.Globalization
@typeparam TVALUE
@inherits InputNumber<TVALUE>

@namespace Gurux.DLMS.AMI.Components

@if (Min != null && Max != null)
{
    <input type="number" class="@CssClass" step="@Step" min="@Min" max="@Max"
    @attributes="AdditionalAttributes" value="@BindConverter.FormatValue(CurrentValueAsString)"
           onchange="@((ChangeEventArgs __e) => CurrentValueAsString = Convert.ToString(__e.Value))" />
}
else if (Min != null)
{
    <input type="number" class="@CssClass" step="@Step" min="@Min"
    @attributes="AdditionalAttributes" value="@BindConverter.FormatValue(CurrentValueAsString)"
           onchange="@((ChangeEventArgs __e) => CurrentValueAsString = Convert.ToString(__e.Value))" />
}
else if (Max != null)
{
    <input type="number" class="@CssClass" step="@Step" max="@Max"
    @attributes="AdditionalAttributes" value="@BindConverter.FormatValue(CurrentValueAsString)"
           onchange="@((ChangeEventArgs __e) => CurrentValueAsString = Convert.ToString(__e.Value))" />
}
else
{
    <input type="number" class="@CssClass" step="@Step"
    @attributes="AdditionalAttributes" value="@BindConverter.FormatValue(CurrentValueAsString)"
           onchange="@((ChangeEventArgs __e) => CurrentValueAsString = Convert.ToString(__e.Value))" />
}

@code {
    private TVALUE? _min;
    private TVALUE? _max;

    /// <summary>
    /// Minimum value.
    /// </summary>
    [Parameter]
    public TVALUE? Min
    {
        get
        {
            return _min;
        }
        set
        {
            _min = value;
        }
    }

    /// <summary>
    /// Maximum value.
    /// </summary>
    [Parameter]
    public TVALUE? Max
    {
        get
        {
            return _max;
        }
        set
        {
            _max = value;
        }
    }

    [Parameter]
    public int Step { get; set; } = 1;

    protected override bool TryParseValueFromString(string? value, [MaybeNullWhen(false)] out TVALUE result, [NotNullWhen(false)] out string? validationErrorMessage)
    {
        validationErrorMessage = null;
        if (BindConverter.TryConvertTo<TVALUE>(value, CultureInfo.InvariantCulture, out result))
        {
            if (Min != null && Convert.ToInt32(result) < Convert.ToInt32(this.Min))
            {
                validationErrorMessage = $"{DisplayName ?? FieldIdentifier.FieldName} must be greater than {this.Min}";
            }

            if (Max != null && Convert.ToInt32(result) > Convert.ToInt32(this.Max))
            {
                validationErrorMessage = $"{DisplayName ?? FieldIdentifier.FieldName} must be less than {this.Max}";
            }
        }

        if (validationErrorMessage is not null)
            result = CurrentValue;

        return validationErrorMessage is null;
    }

    protected override void OnInitialized()
    {
        //Initialize min and max values if not set.
        if (typeof(TVALUE) == typeof(byte))
        {
            if (Min == null)
            {
                BindConverter.TryConvertTo<TVALUE>(byte.MinValue, CultureInfo.InvariantCulture, out _min);
            }
            if (Max == null)
            {
                BindConverter.TryConvertTo<TVALUE>(byte.MaxValue, CultureInfo.InvariantCulture, out _max);
            }
        }
        else if (typeof(TVALUE) == typeof(UInt16))
        {
            if (Min == null)
            {
                BindConverter.TryConvertTo<TVALUE>(UInt16.MinValue, CultureInfo.InvariantCulture, out _min);
            }
            if (Max == null)
            {
                BindConverter.TryConvertTo<TVALUE>(UInt16.MaxValue, CultureInfo.InvariantCulture, out _max);
            }
        }
        else if (typeof(TVALUE) == typeof(UInt32))
        {
            if (Min == null)
            {
                BindConverter.TryConvertTo<TVALUE>(UInt32.MinValue, CultureInfo.InvariantCulture, out _min);
            }
            if (Max == null)
            {
                BindConverter.TryConvertTo<TVALUE>(UInt32.MaxValue, CultureInfo.InvariantCulture, out _max);
            }
        }
        else if (typeof(TVALUE) == typeof(UInt64))
        {
            if (Min == null)
            {
                BindConverter.TryConvertTo<TVALUE>(UInt64.MinValue, CultureInfo.InvariantCulture, out _min);
            }
            if (Max == null)
            {
                BindConverter.TryConvertTo<TVALUE>(UInt64.MaxValue, CultureInfo.InvariantCulture, out _max);
            }
        }
    }
}